#include"ppSpline.h"

ProblemA A; // A题函数

double max_norm(ppSpline<3> &S){
    vector<double> knots = S.get_knots();
    int N = knots.size();
    double m_error = 0.0; 
    for(int i = 0; i < N-1; i++){
        double x = (knots[i] + knots[i+1]) / 2;
        double S_x = S.get_polys()[i].get_value_at_x(x);
        double _error = abs(S_x - A.f(x));
        if(m_error < _error)
            m_error = _error;
    }
    return m_error;
}

/**
 * @brief 将区间[a, b](=[-1,1])给(N-1)等分,取样本点,在 txt 中导出样本点处的值
 * 
 * 对于 N = 6, 11, 21, 41, 81, 分别
 * 导出到`ProblemA_data/?knots_*.txt`中(? = N).
 */
void print_ppSpline(int N, double a, double b, int sample_num){
    double delta = (b-a) / (N-1);
    vector<double> knots;
    double x = a;
    for(int i = 0; i < N; i++){
        knots.push_back(x);
        x += delta;
    }

    string filename = "output/ProblemA_data/" + to_string(N) 
                    + "knots_complete.txt"; // 完全样条        
    ppSpline<3> S = solver(knots, A, complete);
    S.print_plot_data(sample_num / (N-1), filename);
    cout << "max norm: " << max_norm(S) << endl;

    filename = "output/ProblemA_data/" + to_string(N) 
                    + "knots_second.txt";   // second
    S = solver(knots, A, second);
    S.print_plot_data(sample_num / (N-1), filename);
    cout << "max norm: " << max_norm(S) << endl;

    filename = "output/ProblemA_data/" + to_string(N) 
                    + "knots_natural.txt";  // 自然 
    S = solver(knots, A, natural);
    S.print_plot_data(sample_num / (N-1), filename);
    cout << "max norm: " << max_norm(S) << endl;

    return;
}


int main(){
    cout << "-----ProblemA-----\n";

    ifstream input("input/inputA.txt");  
    if(!input.is_open()){  
        cerr << "Unable to open input file!" << endl;  
        exit(-1);
    }  

    string name;
    double a, b;
    int sample_num;
    input >> name >> a >> b >> sample_num;

    int num_of_N; // 本题中, N有5种取值, 将它作为参数输入文件.
    input >> num_of_N;

    for(int i = 0; i < num_of_N; i++){
        int N;
        input >> N;
        print_ppSpline(N, a, b, sample_num);
    }

    A.print_sample_pt(a, b, sample_num, name);

    return 0;
}